﻿// -----------------------------------------------------------------------
// <copyright file="Units.cs" company="DarkBone">
// DarkBone
// </copyright>
// -----------------------------------------------------------------------

namespace DarkBone.Engine.Collections
{
   using System.Collections.Generic;
   using System.Linq;

   using DarkBone.Engine.EventArgs;

   /// <summary>
   /// Contains collection of units
   /// </summary>
   public sealed class Units : List<Unit>
   {
      /// <summary>
      /// Initializes a new instance of the <see cref="Units"/> class.
      /// </summary>
      public Units()
      {
      }

      /// <summary>
      /// Initializes a new instance of the <see cref="Units"/> class.
      /// </summary>
      /// <param name="units">
      /// The units.
      /// </param>
      public Units(IEnumerable<Unit> units)
      {
          this.AddRange(units);
      }

      /// <summary>
      /// Adds new unit
      /// </summary>
      /// <param name="unitNew">The unit new.</param>
      /// <param name="gameSecsElapsed">The game secs elapsed.</param>
      public new void Add(Unit unitNew, int gameSecsElapsed)
      {
         UnitTemplates.GetModelName(ref unitNew);
         UnitTemplates.GetTemplate(ref unitNew);
         unitNew.UpdateTick = gameSecsElapsed;
         base.Add(unitNew);
      }

      /// <summary>
      /// Updates unit in collection
      /// </summary>
      /// <param name="index">The index.</param>
      /// <param name="unitUpdate">Unit to update</param>
      /// <param name="gameSecsElapsed">The game secs elapsed.</param>
      /// <param name="onUnitModified">The on unit modified.</param>
      /// <param name="players">The players.</param>
      public void Update(int index, Unit unitUpdate, int gameSecsElapsed, Collector.UnitModifiedEventHandler onUnitModified, Players players)
      {
         UnitTemplates.GetModelName(ref unitUpdate);
         UnitTemplates.GetTemplate(ref unitUpdate);
         unitUpdate.UpdateTick = gameSecsElapsed;
         if (this[index].UnitStruct.ModelNumber != unitUpdate.UnitStruct.ModelNumber)
         {
            if (onUnitModified != null)
            {
               onUnitModified(this, new EventArgsUnit(unitUpdate, players));
            }
         }

         this[index] = unitUpdate;
      }

      /// <summary>
      /// Get all units of owner
      /// </summary>
      /// <param name="owner">The owner.</param>
      /// <returns>
      /// List of owner's units
      /// </returns>
      public List<Unit> GetUnitsOfOwner(int owner)
      {
         return this.Where(unit => unit.UnitStruct.Owner == owner).ToList();
      }

      /// <summary>
      /// Deletes units that has not been updated for 5000ms
      /// </summary>
      /// <param name="gameSecsElapsed">The game secs elapsed.</param>
      /// <param name="onUnitDestroyed">The on unit destroyed.</param>
      /// <param name="players">The players.</param>
      public void DeleteOld(int gameSecsElapsed, Collector.UnitDestroyedEventHandler onUnitDestroyed, Players players)
      {
         for (var i = this.Count - 1; i >= 0; i--)
         {
            if (this[i].UpdateTick + 2 >= gameSecsElapsed)
            {
               continue;
            }

            if (onUnitDestroyed != null)
            {
               onUnitDestroyed(this, new EventArgsUnit(this[i], players));
            }

            this.RemoveAt(i);
         }
      }
   }
}
